package com.web.web.session;

import com.alibaba.fastjson.JSON;
import com.web.farme.redis.RedisCache;
import com.web.farme.tool.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DefaultSessionUser implements SessionUser {


    private RedisCache redisCache;
    private String redisSessionKey;
    private static final String USER_KEY_PRE = "user.";


    @Override
    public void setRedisCacheAndRedisSessionKey(RedisCache var, String var2) {
        this.redisCache = var;
        this.redisSessionKey = var2;
    }

    @Override
    public void setUserId(Long var) {
        this.set("user_id", String.valueOf(var));
    }

    @Override
    public Long getUserId() {
        return Long.parseLong(this.get("user_id"));
    }

    @Override
    public void setAccount(String var1) {
        this.set("account", var1);
    }

    @Override
    public String getAccount() {
        return this.get("account");
    }

    @Override
    public void setUsername(String var1) {
        this.set("user_name", var1);
    }

    @Override
    public String getUsername() {
        return this.get("user_name");
    }

    @Override
    public void setUserHeadImgUrl(String var1) {
        this.set("user_head_img_url", var1);
    }

    @Override
    public String getUserHeadImgUrl() {
        return this.get("user_head_img_url");
    }

    @Override
    public void setLogin(boolean var1) {
        this.set("is_login", String.valueOf(var1));
    }

    @Override
    public boolean isLogin() {
        return Boolean.parseBoolean(this.get("is_login"));
    }

    @Override
    public void set(String var1, String var2) {
        this.redisCache.setMap(this.redisSessionKey, USER_KEY_PRE + var1, var2);
    }

    @Override
    public String get(String var1) {
        return this.redisCache.getMap(this.redisSessionKey, USER_KEY_PRE + var1);
    }

    /**
     * 通过反射根据这个标准类的字段名去获取redis中的数据
     * 也是通过这个类往redis中set类中的字段和字段带过来的值
     */
    @Override
    public StandardUser getUser() {
        return this.getUser(StandardUser.class);
    }

    @Override
    public <T> T getUser(Class<T> var1) {
        T t;
        try {
            t = var1.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
        Class<?> user = var1;
        List<Field> fieldList = new ArrayList<>();
        List<String> fieldNameList = new ArrayList<>();
        List<String> fieldValueList;
        while (user != Object.class) {
            for (Field declaredField : user.getDeclaredFields()) {
                declaredField.setAccessible(true);
                try {
                    if (declaredField.get(t) != null) {
                        continue;
                    }
                } catch (IllegalAccessException e) {
                    return null;
                }
                fieldList.add(declaredField);
                fieldNameList.add(USER_KEY_PRE + StringUtils.humpToUnderline(declaredField.getName()));
            }
            user = user.getSuperclass();
        }
        fieldValueList = this.redisCache.hmGet(this.redisSessionKey, fieldNameList);
        for (int i = 0; i < fieldValueList.size(); i++) {
            Field field = fieldList.get(i);
            String fieldValue = fieldValueList.get(i);
            if (fieldValue == null) {
                continue;
            }
            if (field.getType().equals(String.class)) {
                try {
                    field.set(t, fieldValue);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    return null;
                }
            } else {
                try {
                    field.set(t, JSON.parseObject(fieldValue, field.getType()));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }
        return t;
    }


    @Override
    public void setUser(Object var1) {
        Class<?> user = var1.getClass();
        Map<String, String> keyAndValue = new HashMap<>();
        while (user != Object.class) {
            for (Field declaredField : user.getDeclaredFields()) {
                declaredField.setAccessible(true);
                Object value = null;
                try {
                    value = declaredField.get(var1);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (value == null) {
                    continue;
                }
                String jsonValue;
                if (value instanceof String) {
                    jsonValue = (String) value;
                } else {
                    jsonValue = JSON.toJSONString(value);
                }
                if (jsonValue == null) {
                    continue;
                }
                keyAndValue.put(USER_KEY_PRE + declaredField, jsonValue);
            }
            user = user.getSuperclass();
        }
        this.redisCache.hmSet(this.redisSessionKey, keyAndValue);
    }
}
